The is
construction is a preferred way to check whether a variable can be cast to some type statically because a compile-time error
will occur in case of incompatible types. The isInstance()
functions from kotlin.reflect.KClass
and java.lang.Class
work differently
and type check at runtime only. Incompatible types will therefore not be detected as early during development, potentially resulting in dead code.
isInstance()
function calls should only be used in dynamic cases when the is
operator can’t be used.
This rule raises an issue when isInstance()
is used and could be replaced with an is
check.
Noncompliant code example
fun f(o: Any): Int {
if (String::class.isInstance(o)) { // Noncompliant
return 42
}
return 0
}
fun f(n: Number): Int {
if (String::class.isInstance(n)) { // Noncompliant
return 42
}
return 0
}
Compliant solution
fun f(o: Any): Int {
if (o is String) { // Compliant
return 42
}
return 0
}
fun f(n: Number): Int {
if (n is String) { // Compile-time error
return 42
}
return 0
}
fun f(o: Any, c: String): Boolean {
return Class.forName(c).isInstance(o) // Compliant, can't use "is" operator here
}